﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using YJKArchUtils.Utils;
using YJKRevitBase.Math;
using YJKRevitBase.TopologySuite;
using YJKRevitKernel.RevitTopologySuite;
using YJKGeometryFuncs;
using YJKRevitDimensionText.OneKeyPlanDim.DimesionDataEx;
using YJKRevitDimensionText.OneKeyPlanDim.Utility;
using YJKRevitDimensionText.Utility;
using YJKRevitDimensionText.VerticalAutoDim;
using YJKRevitDimensionText.VerticalAutoDim.GeoModel;

namespace YJKRevitDimensionText.DimCreator
{
	internal class DimAvoidManager
	{
		public static bool TryAutoAvoidForHorizontal(Autodesk.Revit.DB.Document doc, Dimension inputDim)
		{
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			OcclusionArea occlusionArea = new OcclusionArea(inputDim);
			Transaction transaction = new Transaction(doc, "move");
			try
			{
				XYZ xyz = null;
				XYZ curPoint = null;
				XYZ xyz2 = null;
				List<SegmentReferenceRelation> segmentReferenceRelation = DimAvoidManager.GetSegmentReferenceRelation(inputDim, ref xyz);
				if (xyz == null)
				{
					return false;
				}
				xyz2 = xyz.Normalize().CrossProduct(XYZ.BasisZ.Negate()).Normalize();
				transaction.Start();
				if (segmentReferenceRelation.Count > 1)
				{
					double num = 0.0;
					XYZ xyz3 = segmentReferenceRelation.First<SegmentReferenceRelation>().DimSegment.TextPosition;
					for (int i = 0; i < segmentReferenceRelation.Count; i++)
					{
						double num2 = 0.0;
						double num3 = 0.0;
						double num4 = double.Parse(segmentReferenceRelation[i].DimSegment.Value.ToString());
						double num5;
						if (i == 0)
						{
							num5 = num4 / 2.0;
						}
						else
						{
							num5 = num4;
						}
						if (i != segmentReferenceRelation.Count - 1)
						{
							num += num5;
						}
						occlusionArea.GetOneDimensionInfo(segmentReferenceRelation[i].DimSegment, ref num2, ref num3);
						CurveLoop oneDimSegmentCurveBox = occlusionArea.GetOneDimSegmentCurveBox(segmentReferenceRelation[i].DimSegment, xyz, num2, num3, inputDim.Document.ActiveView);
						double num6 = (num4 + num2) / 2.0;
						if (i == 0)
						{
							if (YJKArch.Utils.Geometry.LessThan(num4, num2))
							{
								segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz3, xyz.Negate(), num6 + DimAvoidManager.m_dval);
								flag3 = true;
							}
						}
						else if (i == segmentReferenceRelation.Count - 1)
						{
							if (YJKArch.Utils.Geometry.LessThan(num4, num2))
							{
								xyz3 = DimAvoidManager.MovePoint(xyz3, xyz, num);
								segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz3, xyz, num6 + DimAvoidManager.m_dval);
							}
						}
						else if (i != 1 || !flag3)
						{
							DimAvoidManager.m_previousTextBox = occlusionArea.GetOneDimSegmentCurveBox(segmentReferenceRelation[i - 1].DimSegment, xyz, num2, num3, null);
							if (DimAvoidManager.IsIntersect(oneDimSegmentCurveBox, DimAvoidManager.m_previousTextBox, xyz, "Horizontal", 0.0))
							{
								XYZ xyz4 = DimAvoidManager.MovePoint(xyz3, xyz, num - num4 / 2.0);
								if (!flag2)
								{
									if (i - 1 == 0)
									{
										curPoint = xyz3;
									}
									else
									{
										curPoint = xyz4;
									}
									flag2 = true;
								}
								if (!flag)
								{
									segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz4, xyz2, num3 + DimAvoidManager.m_dval);
									flag = true;
								}
								else
								{
									XYZ xyz5 = DimAvoidManager.MovePoint(curPoint, xyz, num2 / 2.0);
									List<double> list = new List<double>();
									foreach (Curve curve in oneDimSegmentCurveBox)
									{
										if (xyz.IsAlmostEqualTo(XYZ.BasisX) || xyz.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
										{
											list.Add(curve.GetEndPoint(0).X);
										}
										else
										{
											list.Add(curve.GetEndPoint(0).Y);
										}
									}
									double num7;
									if (xyz.IsAlmostEqualTo(XYZ.BasisX) || xyz.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
									{
										num7 = xyz5.X;
									}
									else
									{
										num7 = xyz5.Y;
									}
                                    if (YJKArch.Utils.Geometry.LessThan(list.Min(), num7))
									{
										segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz4, xyz2.Negate(), num3 + DimAvoidManager.m_dval);
									}
									else
									{
										flag = false;
									}
								}
							}
							else
							{
								flag = false;
								flag2 = false;
							}
						}
					}
				}
				inputDim.get_Parameter(BuiltInParameter.DIM_LEADER).Set(0);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
				return false;
			}
			return true;
		}

		public static List<DimensionSegmentInfor> TryAutoAvoidForVertical(Autodesk.Revit.DB.Document doc, Dimension inputDim)
		{
			List<DimensionSegmentInfor> list = new List<DimensionSegmentInfor>();
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			OcclusionArea occlusionArea = new OcclusionArea(inputDim);
			Transaction transaction = new Transaction(doc, "move");
			try
			{
				XYZ xyz = null;
				XYZ curPoint = null;
				XYZ xyz2 = null;
				List<SegmentReferenceRelation> segmentReferenceRelation = DimAvoidManager.GetSegmentReferenceRelation(inputDim, ref xyz);
				if (xyz == null)
				{
					return list;
				}
				transaction.Start();
				if (segmentReferenceRelation.Count > 1)
				{
					double num = 0.0;
					XYZ xyz3 = segmentReferenceRelation.First<SegmentReferenceRelation>().DimSegment.TextPosition;
					for (int i = 0; i < segmentReferenceRelation.Count; i++)
					{
						DimensionSegmentInfor item = default(DimensionSegmentInfor);
						item.Index = i;
						List<double> list2 = new List<double>();
						double num2 = 0.0;
						double num3 = 0.0;
						double num4 = 0.0;
						num2 = double.Parse(segmentReferenceRelation[i].DimSegment.Value.ToString());
						double num5;
						if (i == 0)
						{
							num5 = num2 / 2.0;
						}
						else
						{
							num5 = num2;
						}
						if (i != segmentReferenceRelation.Count - 1)
						{
							num += num5;
						}
						occlusionArea.GetOneDimensionInfo(segmentReferenceRelation[i].DimSegment, ref num3, ref num4);
						CurveLoop oneDimSegmentCurveBox = occlusionArea.GetOneDimSegmentCurveBox(segmentReferenceRelation[i].DimSegment, xyz, num3, num4, inputDim.Document.ActiveView);
						if (!flag3)
						{
							DimAvoidManager.GetMoveVector(oneDimSegmentCurveBox, xyz, ref xyz2);
							flag3 = true;
						}
						foreach (Curve curve in oneDimSegmentCurveBox)
						{
							list2.Add(curve.GetEndPoint(0).Z);
						}
						if (xyz.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
						{
							DimAvoidManager.m_dicPreTextBoxZ.Add(new KeyValuePair<int, double>(i, list2.Min()));
						}
						else if (xyz.IsAlmostEqualTo(XYZ.BasisZ))
						{
							DimAvoidManager.m_dicPreTextBoxZ.Add(new KeyValuePair<int, double>(i, list2.Max()));
						}
						double num6 = (num2 + num3) / 2.0;
						if (i == 0)
						{
							if (YJKArch.Utils.Geometry.LessThan(num2, num3))
							{
								flag4 = true;
								segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz3, xyz.Negate(), num6 + DimAvoidManager.m_dval);
								item.Direction = xyz.Negate();
								item.Distance = num6 + DimAvoidManager.m_dval;
							}
						}
						else if (i == segmentReferenceRelation.Count - 1)
						{
							if (YJKArch.Utils.Geometry.LessThan(num2, num3))
							{
								xyz3 = DimAvoidManager.MovePoint(xyz3, xyz, num);
								segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz3, xyz, num6 + DimAvoidManager.m_dval);
								item.Direction = xyz;
								item.Distance = num6 + DimAvoidManager.m_dval;
							}
						}
						else
						{
							bool flag5 = !flag4 && DimAvoidManager.IsIntersect(oneDimSegmentCurveBox, DimAvoidManager.m_previousTextBox, xyz, "Vertical", DimAvoidManager.m_dicPreTextBoxZ[i - 1].Value);
							if (flag5)
							{
								XYZ xyz4 = DimAvoidManager.MovePoint(xyz3, xyz, num - num2 / 2.0);
								if (!flag2)
								{
									if (i - 1 == 0)
									{
										curPoint = xyz3;
									}
									else
									{
										curPoint = xyz4;
									}
									flag2 = true;
								}
								if (!flag)
								{
									if (xyz.IsAlmostEqualTo(XYZ.BasisZ))
									{
										segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz4, xyz2.Negate(), num4 + DimAvoidManager.m_dval);
										item.Direction = xyz2.Negate();
										item.Distance = num4 + DimAvoidManager.m_dval;
									}
									else
									{
										segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz4, xyz2, num4 + DimAvoidManager.m_dval);
										item.Direction = xyz2;
										item.Distance = num4 + DimAvoidManager.m_dval;
									}
									flag = true;
								}
								else
								{
									XYZ xyz5 = DimAvoidManager.MovePoint(curPoint, xyz, num3 / 2.0);
									List<double> list3 = new List<double>();
									foreach (Curve curve2 in oneDimSegmentCurveBox)
									{
										list3.Add(curve2.GetEndPoint(0).Z);
									}
									if (xyz.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
									{
										if (YJKArch.Utils.Geometry.LessThan(xyz5.Z, list3.Max()))
										{
											segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz4, xyz2.Negate(), num4 + DimAvoidManager.m_dval);
											item.Direction = xyz2.Negate();
											item.Distance = num4 + DimAvoidManager.m_dval;
										}
										else
										{
											flag = false;
										}
									}
									else if (YJKArch.Utils.Geometry.LessThan(list3.Min(), xyz5.Z))
									{
										segmentReferenceRelation[i].DimSegment.TextPosition = DimAvoidManager.MovePoint(xyz4, xyz2, num4 + DimAvoidManager.m_dval);
										item.Direction = xyz2;
										item.Distance = num4 + DimAvoidManager.m_dval;
									}
									else
									{
										flag = false;
									}
								}
							}
							else
							{
								flag = false;
								flag2 = false;
							}
						}
						list.Add(item);
					}
				}
				inputDim.get_Parameter(BuiltInParameter.DIM_LEADER).Set(0);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
				return list;
			}
			return list;
		}

		public static bool TryAutoAvoidElementForVertical(Autodesk.Revit.DB.Document doc, Dimension inputDim, List<IPlanarGeo> lstAllWindDoorGeo, List<IPlanarGeo> lstWindDoorGeoWithDimRef, Transform transformWcs2Ecs, List<DimensionSegmentInfor> lstSegmentInfor, List<Dimension> lstThreeDimLines)
		{
			if (doc == null || inputDim == null || transformWcs2Ecs == null || lstSegmentInfor.Count == 0 || lstWindDoorGeoWithDimRef.Count == 0)
			{
				return false;
			}
			Transaction transaction = new Transaction(doc);
			bool result;
			try
			{
				transaction.Start("avoid element");
				double windDoorWholeWidth = DimAvoidManager.GetWindDoorWholeWidth(lstWindDoorGeoWithDimRef);
				int num = 1;
				if (lstThreeDimLines != null && lstThreeDimLines.Count != 0)
				{
					DimAvoidManager.TryAvoidThreeDimensionLine(ref inputDim, ref num, doc, windDoorWholeWidth, transformWcs2Ecs, lstSegmentInfor, lstThreeDimLines);
				}
				if (lstAllWindDoorGeo.Count != 0 && num != 0)
				{
					DimAvoidManager.TryAvoidWindDoorComponent(ref inputDim, ref num, doc, lstAllWindDoorGeo, windDoorWholeWidth, transformWcs2Ecs, lstSegmentInfor);
				}
				transaction.Commit();
				result = true;
			}
			catch (Exception ex)
			{
				if (1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
				throw ex;
			}
			return result;
		}

		public static bool TryAutoAvoidElementForHorizontal(Autodesk.Revit.DB.Document doc, List<Dimension> inputDims)
		{
			DimAvoidManager.m_doc = doc;
			OcclusionArea.m_doc = doc;
			List<Dimension> lstDimCurDoc = (from d in new FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(typeof(Dimension)).OfCategory(BuiltInCategory.OST_Dimensions)
			select d as Dimension).ToList<Dimension>();
			try
			{
				foreach (Dimension dimension in inputDims)
				{
					try
					{
						Curve curve = null;
						List<CurveLoop> lstUseDimCurveLoop = new List<CurveLoop>();
						XYZ dimVector = DimAvoidManager.GetDimVector(dimension, ref curve, 2);
						if (!(curve == null))
						{
							XYZ origin = (curve as Line).Origin;
							XYZ ptEnd = origin;
							List<Curve> oneDimensionOffsetRange = DimAvoidManager.GetOneDimensionOffsetRange(curve, dimVector, 0.0);
							if (oneDimensionOffsetRange != null)
							{
								DimAvoidManager.GetParallerWalls(curve, oneDimensionOffsetRange, ref lstUseDimCurveLoop);
								DimAvoidManager.GetIndependentTagInDimRange(oneDimensionOffsetRange, ref lstUseDimCurveLoop);
								DimAvoidManager.GetStairsCurveLoop(oneDimensionOffsetRange, ref lstUseDimCurveLoop);
								DimAvoidManager.GetDoorWindowCurveLoopInRange(oneDimensionOffsetRange, ref lstUseDimCurveLoop);
								DimAvoidManager.GetOpeningCurveLoopInRange(ref lstUseDimCurveLoop);
								DimAvoidManager.GetColumnCurveLoopInRange(oneDimensionOffsetRange, ref lstUseDimCurveLoop);
								DimAvoidManager.GetOtherDimCurveLoop(dimension, lstDimCurDoc, oneDimensionOffsetRange, ref lstUseDimCurveLoop);
								if (DimAvoidManager.CalcDimMovePoint(dimension, lstUseDimCurveLoop, dimVector, origin, ref ptEnd) < 7)
								{
									CommonInterface.MoveElement(dimension, origin, ptEnd, DimAvoidManager.m_doc);
								}
							}
						}
					}
					catch (Exception)
					{
					}
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		public static void ClearCache()
		{
			DimAvoidManager.m_dicPreTextBoxZ.Clear();
		}

		public static List<Curve> GetOneDimensionOffsetRange(Curve curDimCurve, XYZ direction, double dOffsetVal = 0.0)
		{
			List<Curve> list = new List<Curve>();
			try
			{
				double num;
				if (!YJKArch.Utils.Geometry.IsEqual(dOffsetVal, 0.0))
				{
					num = dOffsetVal;
				}
				else
				{
					num = DimAvoidManager.m_dOffsetVal;
				}
				XYZ xyz = direction.Normalize().CrossProduct(XYZ.BasisZ.Negate()).Normalize();
				Line input = DimAvoidManager.CreateSameOffset(curDimCurve, num, xyz) as Line;
				Curve curve = DimAvoidManager.CreateSameOffset(input, 0.0, xyz) as Line;
				Curve curve2 = DimAvoidManager.CreateSameOffset(input, num * 2.0, xyz.Negate()) as Line;
				list.Add(Line.CreateBound(curve2.GetEndPoint(0), curve.GetEndPoint(0)));
				list.Add(curve);
				list.Add(Line.CreateBound(curve.GetEndPoint(1), curve2.GetEndPoint(1)));
				list.Add(DimAvoidManager.CreateReversedUtility(curve2));
			}
			catch (Exception)
			{
				return null;
			}
			return list;
		}

		private static XYZ GetDimVector(Dimension dim, ref Curve CurDimCurve, int OffsetMultiple = 2)
		{
			ReferenceArray references = dim.References;
			DimensionSegmentArray segments = dim.Segments;
			if (segments.Size == 0)
			{
				CurDimCurve = DimAvoidManager.GetSpecialDimCurve(dim);
				return (dim.Curve as Line).Direction;
			}
            XYZ origin = segments.get_Item(0).Origin;
			XYZ origin2 = segments.get_Item(segments.Size - 1).Origin;
			XYZ xyz = (origin2 - origin).Normalize();
            double moveVal = AssistFunc.mmToFeet(double.Parse(segments.get_Item(0).ValueString) * (double)OffsetMultiple);
            double moveVal2 = AssistFunc.mmToFeet(double.Parse(segments.get_Item(segments.Size - 1).ValueString) * (double)OffsetMultiple);
			CurDimCurve = Line.CreateBound(DimAvoidManager.MovePoint(origin, xyz.Negate(), moveVal), DimAvoidManager.MovePoint(origin2, xyz, moveVal2));
			return xyz;
		}

		private static void GetDoorWindowCurveLoopInRange(List<Curve> lstCurDimRange, ref List<CurveLoop> lstUseDimCurveLoop)
		{
			CurveLoop twoLoop = null;
			try
			{
				twoLoop = CurveLoop.Create(lstCurDimRange);
			}
			catch (Exception)
			{
				return;
			}
			foreach (WallDataEx wallDataEx in DimAvoidManager.m_lstAllDoorWinInfo)
			{
				try
				{
					double width = (DimAvoidManager.m_doc.GetElement(wallDataEx.WallId) as Wall).Width;
					foreach (DoorWinDataEx doorWinDataEx in wallDataEx.WallWindows)
					{
						if (doorWinDataEx.doorWinLine != null)
						{
							List<Curve> oneDimensionOffsetRange = DimAvoidManager.GetOneDimensionOffsetRange(doorWinDataEx.doorWinLine, doorWinDataEx.doorWinLine.Direction, width / 2.0);
							if (oneDimensionOffsetRange != null && DimAvoidManager.IsIntersect(CurveLoop.Create(oneDimensionOffsetRange), twoLoop, null, "Horizontal", 0.0))
							{
								lstUseDimCurveLoop.Add(CurveLoop.Create(oneDimensionOffsetRange));
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
		}

		private static void GetOpeningCurveLoopInRange(ref List<CurveLoop> lstUseDimCurveLoop)
		{
			foreach (Element element in new FilteredElementCollector(DimAvoidManager.m_doc, DimAvoidManager.m_doc.ActiveView.Id).OfClass(typeof(Opening)).ToElements())
			{
				Opening opening = (Opening)element;
				try
				{
					lstUseDimCurveLoop.AddRange(OcclusionArea.GetOpeningCurveLoop(opening));
				}
				catch (Exception)
				{
				}
			}
		}

		private static void GetColumnCurveLoopInRange(List<Curve> lstCurDimRange, ref List<CurveLoop> lstUseDimCurveLoop)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			DimAvoidManager.GetColumns(ref list);
			foreach (FamilyInstance familyInstance in list)
			{
				try
				{
					XYZ point = (familyInstance.Location as LocationPoint).Point;
                    if (YJKGeometryFuncs.Geometry.PointInPloygon(lstCurDimRange, point) == 1)
					{
						List<Face> list2 = new List<Face>();
						OcclusionArea.GetElementFace(ref list2, familyInstance, XYZ.BasisZ);
						if (list2 != null && list2.Count != 0)
						{
							foreach (Face face in list2)
							{
								lstUseDimCurveLoop.Add(CommonInterface.GetXYPlaneCurve(face.GetEdgesAsCurveLoops().First<CurveLoop>()));
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
		}

		private static void GetParallerWalls(Curve curDimCv, List<Curve> lstCurDimRange, ref List<CurveLoop> lstResUseCurveLoop)
		{
			List<Element> list = new List<Element>();
			foreach (Element element in ((IEnumerable<Element>)new FilteredElementCollector(DimAvoidManager.m_doc).OfClass(typeof(Wall)).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements().ToList<Element>()))
			{
				Wall wall = (Wall)element;
				if (wall != null)
				{
					try
					{
						Curve curve = (wall.Location as LocationCurve).Curve;
						if (curve != null && CurveAssistFunc.IsParallel(curDimCv, curve) && DimAvoidManager.IsInRange(curve, lstCurDimRange))
						{
							list.Add(wall);
						}
					}
					catch
					{
					}
				}
			}
			lstResUseCurveLoop.AddRange(OcclusionArea.GetFaceCurveLoop(list));
		}

		private static void GetIndependentTagInDimRange(List<Curve> lstCurDimRange, ref List<CurveLoop> lstUseDimCurveLoop)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(DimAvoidManager.m_doc).OfCategory(BuiltInCategory.OST_DoorTags).WhereElementIsNotElementType();
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(DimAvoidManager.m_doc).OfCategory(BuiltInCategory.OST_WindowTags).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				try
				{
					IndependentTag independentTag = element as IndependentTag;
					CurveLoop independentTagLoop = OcclusionArea.GetIndependentTagLoop(independentTag, DimAvoidManager.m_doc);
					if (independentTag != null && independentTagLoop != null && DimAvoidManager.IsIntersect(CurveLoop.Create(lstCurDimRange), independentTagLoop, null, "Horizontal", 0.0))
					{
						lstUseDimCurveLoop.Add(independentTagLoop);
					}
				}
				catch (Exception)
				{
				}
			}
			foreach (Element element2 in filteredElementCollector2)
			{
				try
				{
					IndependentTag independentTag2 = element2 as IndependentTag;
					CurveLoop independentTagLoop2 = OcclusionArea.GetIndependentTagLoop(independentTag2, DimAvoidManager.m_doc);
					if (independentTag2 != null && independentTagLoop2 != null && DimAvoidManager.IsIntersect(CurveLoop.Create(lstCurDimRange), independentTagLoop2, null, "Horizontal", 0.0))
					{
						lstUseDimCurveLoop.Add(independentTagLoop2);
					}
				}
				catch (Exception)
				{
				}
			}
		}

		private static void GetStairsCurveLoop(List<Curve> lstCurDimRange, ref List<CurveLoop> lstUseDimCurveLoop)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(DimAvoidManager.m_doc, DimAvoidManager.m_doc.ActiveView.Id);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(Stairs));
			foreach (Element element in filteredElementCollector.WherePasses(elementClassFilter).ToElements())
			{
				if (element != null && element is Stairs)
				{
					try
					{
						Stairs curStairs = element as Stairs;
						foreach (CurveLoop curveLoop in OcclusionArea.GetStairsCurveLoop(DimAvoidManager.m_doc, curStairs))
						{
							if (curveLoop != null && DimAvoidManager.IsIntersect(curveLoop, CurveLoop.Create(lstCurDimRange), null, "Horizontal", 0.0))
							{
								lstUseDimCurveLoop.Add(curveLoop);
							}
						}
					}
					catch (Exception)
					{
					}
				}
			}
		}

		private static void GetOtherDimCurveLoop(Dimension curDim, List<Dimension> lstDimCurDoc, List<Curve> lstCurDimRange, ref List<CurveLoop> lstUseDimCurveLoop)
		{
			List<Dimension> list = new List<Dimension>();
			foreach (Dimension dimension in lstDimCurDoc)
			{
				if (!(dimension.Id == curDim.Id))
				{
					list.Add(dimension);
				}
			}
			foreach (Dimension dimension2 in list)
			{
				try
				{
					Curve curve = null;
					DimAvoidManager.GetDimVector(dimension2, ref curve, 1);
					if (curve != null && DimAvoidManager.IsInRange(curve, lstCurDimRange))
					{
						lstUseDimCurveLoop.AddRange(OcclusionArea.GetSizeDimCurveLoop(dimension2));
					}
				}
				catch (Exception)
				{
				}
			}
		}

		private static void GetColumns(ref List<FamilyInstance> selColumns)
		{
			foreach (Element element in new FilteredElementCollector(DimAvoidManager.m_doc, DimAvoidManager.m_doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_Columns).OfClass(typeof(FamilyInstance)).ToElements())
			{
				FamilyInstance item = element as FamilyInstance;
				selColumns.Add(item);
			}
			foreach (Element element2 in new FilteredElementCollector(DimAvoidManager.m_doc, DimAvoidManager.m_doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_StructuralColumns).OfClass(typeof(FamilyInstance)).ToElements())
			{
				FamilyInstance item2 = element2 as FamilyInstance;
				selColumns.Add(item2);
			}
		}

		private static int CalcDimMovePoint(Dimension CurDim, List<CurveLoop> lstUseDimCurveLoop, XYZ dimVector, XYZ ptOrigin, ref XYZ ptNewOrigin)
		{
			int num = 0;
			int i = 0;
			new List<ElementId>();
			List<CurveLoop> list = OcclusionArea.GetSizeDimCurveLoop(CurDim);
			List<CurveLoop> list2 = new List<CurveLoop>();
			list2.AddRange(list);
			XYZ xyz = dimVector.Normalize().CrossProduct(XYZ.BasisZ.Negate()).Normalize();
			XYZ vtOffset = xyz;
			bool flag = true;
			while (i < 7)
			{
				ptNewOrigin = CommonInterface.GetNextPositionByOffset(num, DimAvoidManager.m_dDimMoveVal, ptOrigin, vtOffset);
				list = CommonInterface.MoveLstCurve(list2, ptOrigin, ptNewOrigin);
				using (List<CurveLoop>.Enumerator enumerator = list.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						if (CommonInterface.IsExistOcclusion(enumerator.Current, lstUseDimCurveLoop))
						{
							flag = false;
							break;
						}
					}
				}
				if (flag)
				{
					return i;
				}
				if (i % 2 == 0)
				{
					vtOffset = xyz.Negate();
					num++;
				}
				else
				{
					vtOffset = xyz;
				}
				flag = true;
				i++;
			}
			return i;
		}

		private static Curve GetSpecialDimCurve(Dimension CurDim)
		{
			ReferenceArray references = CurDim.References;
            if (references.get_Item(0) == null || references.get_Item(references.Size - 1) == null)
			{
				return null;
			}
			Curve curve = null;
			Curve curve2 = null;
			try
			{
                curve = (DimAvoidManager.m_doc.GetElement(references.get_Item(0).ElementId) as DetailCurve).GeometryCurve;
				curve2 = (DimAvoidManager.m_doc.GetElement(references.get_Item(references.Size - 1).ElementId) as DetailCurve).GeometryCurve;
			}
			catch (Exception)
			{
				try
				{
                    curve = (DimAvoidManager.m_doc.GetElement(references.get_Item(0).ElementId) as ModelCurve).GeometryCurve;
                    curve2 = (DimAvoidManager.m_doc.GetElement(references.get_Item(references.Size - 1).ElementId) as ModelCurve).GeometryCurve;
				}
				catch (Exception)
				{
					return null;
				}
			}
			return Line.CreateBound(curve.GetEndPoint(0), curve2.GetEndPoint(0));
		}

		private static bool IsInRange(Curve curWallCv, List<Curve> lstCurDimRange)
		{
			try
			{
				XYZ endPoint = curWallCv.GetEndPoint(0);
				XYZ endPoint2 = curWallCv.GetEndPoint(1);
				XYZ xyz = YJKArch.Utils.Geometry.CalculatMidPoint(endPoint, endPoint2);
                if (YJKGeometryFuncs.Geometry.PointInPloygon(lstCurDimRange, endPoint) == 1 || YJKGeometryFuncs.Geometry.PointInPloygon(lstCurDimRange, endPoint2) == 1 || YJKGeometryFuncs.Geometry.PointInPloygon(lstCurDimRange, xyz) == 1)
				{
					return true;
				}
			}
			catch (Exception)
			{
				return false;
			}
			return false;
		}

		private static XYZ MovePoint(XYZ curPoint, XYZ dir, double moveVal)
		{
			return curPoint + dir * moveVal;
		}

		private static Curve CreateSameOffset(Curve input, double offsetDist, XYZ normal)
		{
			if (input is Line)
			{
                return YJKArchUtils.Utils.Geometry.OffsetLine(input as Line, offsetDist, normal);
			}
			if (input is Arc)
			{
                return YJKArchUtils.Utils.Geometry.OffsetArc(DimAvoidManager.m_doc.Application, input as Arc, offsetDist);
			}
			return null;
		}

		private static Curve CreateReversedUtility(Curve input)
		{
			try
			{
				if (input is Line)
				{
					return Line.CreateBound(input.GetEndPoint(1), input.GetEndPoint(0));
				}
				if (input is Arc)
				{
					XYZ center = (input as Arc).Center;
					return Arc.Create(input.GetEndPoint(1), input.GetEndPoint(0), center);
				}
			}
			catch (Exception)
			{
			}
			return null;
		}

		private static void GetMoveVector(CurveLoop loop, XYZ dir, ref XYZ vVector)
		{
			new List<XYZ>();
			foreach (Curve curve in loop)
			{
				XYZ xyz = (curve.GetEndPoint(0) - curve.GetEndPoint(1)).Normalize();
				if (GeometryHelper.VectorVerticalVector(xyz, dir))
				{
					vVector = xyz;
					break;
				}
			}
		}

		private static bool IsIntersect(CurveLoop oneLoop, CurveLoop twoLoop, XYZ vVector, string strOrderType, double m_dPreTextBoxZ = 0.0)
		{
			List<double> list = new List<double>();
			try
			{
				if (strOrderType.Equals("Horizontal"))
				{
					RevitPolygonDataBean revitPolygonDataBean = new RevitPolygonDataBean(oneLoop, null, 3);
					RevitPolygonDataBean revitPolygonDataBean2 = new RevitPolygonDataBean(twoLoop, null, 3);
                    if (DimAvoidManager.m_useRelateOperater.TryGetPolygonRelate(revitPolygonDataBean, revitPolygonDataBean2, out DimAvoidManager.tempRelate) && (int)DimAvoidManager.tempRelate != 1)
					{
						return true;
					}
				}
				else if (strOrderType.Equals("Vertical"))
				{
					foreach (Curve curve in oneLoop)
					{
						list.Add(curve.GetEndPoint(0).Z);
					}
					if (vVector.IsAlmostEqualTo(XYZ.BasisZ.Negate()) && YJKArch.Utils.Geometry.LessThan(list.Max(), m_dPreTextBoxZ, 0.0001))
					{
						return false;
					}
					if (vVector.IsAlmostEqualTo(XYZ.BasisZ) && YJKArch.Utils.Geometry.LessThan(m_dPreTextBoxZ, list.Min(), 0.0001))
					{
						return false;
					}
					return true;
				}
			}
			catch (Exception)
			{
				return false;
			}
			return false;
		}

		private static List<SegmentReferenceRelation> GetSegmentReferenceRelation(Dimension dim, ref XYZ direction)
		{
			List<SegmentReferenceRelation> list = new List<SegmentReferenceRelation>();
			Curve curve = dim.Curve;
			ReferenceArray references = dim.References;
			DimensionSegmentArray segments = dim.Segments;
			if (segments.Size == 0)
			{
				return list;
			}
            XYZ origin = segments.get_Item(0).Origin;
			XYZ origin2 = segments.get_Item(segments.Size - 1).Origin;
			direction = (origin2 - origin).Normalize();
			for (int i = 0; i < segments.Size; i++)
			{
				DimensionSegment dimensionSegment = segments.get_Item(i);
				List<Reference> list2 = new List<Reference>();
				list2.Add(references.get_Item(i));
                list2.Add(references.get_Item(i + 1));
				List<XYZ> dimensionMarkPoint = DimAvoidManager.GetDimensionMarkPoint(direction, dimensionSegment);
				list.Add(new SegmentReferenceRelation
				{
					Index = i,
					DimSegment = dimensionSegment,
					DimReferences = list2,
					DimMarkPoints = dimensionMarkPoint
				});
			}
			return list;
		}

		private static List<XYZ> GetDimensionMarkPoint(XYZ direction, DimensionSegment segment)
		{
			List<XYZ> list = new List<XYZ>();
			XYZ origin = segment.Origin;
			double num = segment.Value ?? -1.0;
			if (num == 0.0)
			{
				list.Add(origin);
				list.Add(origin);
			}
			else
			{
				XYZ item = origin + -direction * (num / 2.0);
				list.Add(item);
				item = origin + direction * (num / 2.0);
				list.Add(item);
			}
			return list;
		}

		private static void TryAvoidThreeDimensionLine(ref Dimension dimension, ref int nAvoidCount, Autodesk.Revit.DB.Document doc, double dWidth, Transform transformWcs2Ecs, List<DimensionSegmentInfor> lstSegmentInfor, List<Dimension> lstThreeDimLines)
		{
			if (dimension == null || doc == null || transformWcs2Ecs == null || lstSegmentInfor.Count == 0 || lstThreeDimLines.Count == 0)
			{
				return;
			}
			try
			{
				double[] array = new double[]
				{
					1800.0,
					1200.0,
					1500.0,
					1800.0,
					2100.0,
					2400.0
				};
				XYZ xyz = doc.ActiveView.RightDirection.Normalize();
				XYZ xyz2 = null;
				XYZ xyz3 = null;
				DimAvoidManager.GetEcsPoint(ref xyz2, ref xyz3, doc, dimension, transformWcs2Ecs, lstSegmentInfor);
				if (xyz2 != null && xyz3 != null)
				{
					bool flag = false;
					do
					{
						int i = 0;
						while (i < lstThreeDimLines.Count)
						{
							Dimension dimension2 = lstThreeDimLines[i];
							XYZ xyz4 = null;
							XYZ xyz5 = null;
							DimAvoidManager.GetEcsPoint(ref xyz4, ref xyz5, doc, dimension2, transformWcs2Ecs, null);
							if (!MathUtility.GreaterThan(xyz4.X, xyz3.X, 1E-06) && !MathUtility.LessThan(xyz5.X, xyz2.X, 1E-06) && !MathUtility.GreaterThan(xyz4.Y, xyz3.Y, 1E-06) && !MathUtility.LessThan(xyz5.Y, xyz2.Y, 1E-06))
							{
								if (6 == nAvoidCount)
								{
									nAvoidCount = 0;
								}
								XYZ xyz6;
								if (nAvoidCount == 0)
								{
									xyz6 = xyz * (UnitUtility.MMToFeet(array[nAvoidCount]) + dWidth);
									ElementTransformUtils.MoveElement(doc, dimension.Id, xyz6);
									flag = true;
									break;
								}
								if (1 == nAvoidCount % 2)
								{
									xyz6 = -xyz * (UnitUtility.MMToFeet(array[nAvoidCount]) + dWidth);
								}
								else
								{
									xyz6 = xyz * (UnitUtility.MMToFeet(array[nAvoidCount]) + dWidth);
								}
								ElementTransformUtils.MoveElement(doc, dimension.Id, xyz6);
								nAvoidCount++;
								if (i == lstThreeDimLines.Count - 1)
								{
									flag = true;
									break;
								}
								break;
							}
							else
							{
								if (i == lstThreeDimLines.Count - 1)
								{
									flag = true;
									break;
								}
								i++;
							}
						}
					}
					while (!flag);
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		private static void TryAvoidWindDoorComponent(ref Dimension dimension, ref int nAvoidCount, Autodesk.Revit.DB.Document doc, List<IPlanarGeo> lstWindDoorGeo, double dWidth, Transform transformWcs2Ecs, List<DimensionSegmentInfor> lstSegmentInfor)
		{
			if (dimension.Segments.Size == 0 || doc == null || lstWindDoorGeo.Count == 0 || transformWcs2Ecs == null || lstSegmentInfor.Count == 0)
			{
				return;
			}
			try
			{
				double[] array = new double[]
				{
					1800.0,
					1200.0,
					1500.0,
					1800.0,
					2100.0,
					2400.0
				};
				XYZ xyz = doc.ActiveView.RightDirection.Normalize();
				XYZ xyz4;
				for (;;)
				{
					bool flag = false;
					XYZ xyz2 = null;
					XYZ xyz3 = null;
					DimAvoidManager.GetEcsPoint(ref xyz2, ref xyz3, doc, dimension, transformWcs2Ecs, lstSegmentInfor);
					if (xyz2 == null || xyz3 == null)
					{
						break;
					}
					foreach (IPlanarGeo planarGeo in lstWindDoorGeo)
					{
						if (!MathUtility.GreaterThan(planarGeo.Min2DPointECS.X, xyz3.X, 1E-06) && !MathUtility.LessThan(planarGeo.Max2DPointECS.X, xyz2.X, 1E-06) && !MathUtility.GreaterThan(planarGeo.Min2DPointECS.Y, xyz3.Y, 1E-06) && !MathUtility.LessThan(planarGeo.Max2DPointECS.Y, xyz2.Y, 1E-06))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						break;
					}
					if (6 == nAvoidCount)
					{
						nAvoidCount = 0;
					}
					if (nAvoidCount == 0)
					{
						goto Block_11;
					}
					if (1 == nAvoidCount % 2)
					{
						xyz4 = -xyz * (UnitUtility.MMToFeet(array[nAvoidCount]) + dWidth);
					}
					else
					{
						xyz4 = xyz * (UnitUtility.MMToFeet(array[nAvoidCount]) + dWidth);
					}
					ElementTransformUtils.MoveElement(doc, dimension.Id, xyz4);
					nAvoidCount++;
				}
				return;
				Block_11:
				xyz4 = xyz * (UnitUtility.MMToFeet(array[nAvoidCount]) + dWidth);
				ElementTransformUtils.MoveElement(doc, dimension.Id, xyz4);
			}
			catch
			{
			}
		}

		private static void GetEcsPoint(ref XYZ ptMinEcs, ref XYZ ptMaxEcs, Autodesk.Revit.DB.Document doc, Dimension dimension, Transform transformWcs2Ecs, List<DimensionSegmentInfor> lstSegmentInfor)
		{
			if (doc == null || dimension == null)
			{
				ptMinEcs = null;
				ptMaxEcs = null;
				return;
			}
			try
			{
				XYZ xyz = doc.ActiveView.RightDirection.Normalize();
				XYZ xyz2 = doc.ActiveView.UpDirection.Normalize();
				OcclusionArea occlusionArea = new OcclusionArea(dimension);
				XYZ xyz3 = null;
				List<SegmentReferenceRelation> segmentReferenceRelation = DimAvoidManager.GetSegmentReferenceRelation(dimension, ref xyz3);
				double num = 0.0;
				double num2 = 0.0;
				XYZ xyz4;
				XYZ xyz5;
				if (segmentReferenceRelation.Count == 0)
				{
					occlusionArea.GetOnlyOneDimensionSegmentInfo(dimension.ValueString, ref num, ref num2);
					xyz4 = dimension.Origin - xyz * num2 - xyz2 * (num / 2.0);
					xyz5 = dimension.Origin + xyz2 * (num / 2.0);
				}
				else
				{
					occlusionArea.GetOneDimensionInfo(segmentReferenceRelation[0].DimSegment, ref num, ref num2);
					xyz4 = segmentReferenceRelation[0].DimSegment.Origin - xyz * num2 - xyz2 * (num / 2.0);
					occlusionArea.GetOneDimensionInfo(segmentReferenceRelation[segmentReferenceRelation.Count - 1].DimSegment, ref num, ref num2);
					xyz5 = segmentReferenceRelation[segmentReferenceRelation.Count - 1].DimSegment.Origin + xyz2 * (num / 2.0);
				}
				ptMinEcs = transformWcs2Ecs.OfPoint(xyz4);
				ptMaxEcs = transformWcs2Ecs.OfPoint(xyz5);
				if (MathUtility.GreaterThan(ptMinEcs.X, ptMaxEcs.X, 1E-06))
				{
					XYZ xyz6 = ptMinEcs;
					ptMinEcs = ptMaxEcs;
					ptMaxEcs = xyz6;
				}
				if (lstSegmentInfor != null)
				{
					for (int i = 0; i < lstSegmentInfor.Count; i++)
					{
						DimensionSegmentInfor dimensionSegmentInfor = lstSegmentInfor[i];
						if (dimensionSegmentInfor.Direction != null)
						{
							XYZ xyz7 = segmentReferenceRelation[i].DimSegment.Origin + dimensionSegmentInfor.Direction * dimensionSegmentInfor.Distance;
							occlusionArea.GetOneDimensionInfo(segmentReferenceRelation[i].DimSegment, ref num, ref num2);
							XYZ xyz8 = transformWcs2Ecs.OfPoint(xyz7 - xyz * num2 - xyz2 * (num / 2.0));
							XYZ xyz9 = transformWcs2Ecs.OfPoint(xyz7 + xyz2 * (num / 2.0));
							if (MathUtility.GreaterThan(ptMinEcs.X, xyz8.X, 1E-06))
							{
								ptMinEcs = new XYZ(xyz8.X, ptMinEcs.Y, ptMinEcs.Z);
							}
							else if (MathUtility.GreaterThan(ptMinEcs.X, xyz9.X, 1E-06))
							{
								ptMinEcs = new XYZ(xyz9.X, ptMinEcs.Y, ptMinEcs.Z);
							}
							if (MathUtility.LessThan(ptMaxEcs.X, xyz8.X, 1E-06))
							{
								ptMaxEcs = new XYZ(xyz8.X, ptMaxEcs.Y, ptMaxEcs.Z);
							}
							else if (MathUtility.LessThan(ptMaxEcs.X, xyz9.X, 1E-06))
							{
								ptMaxEcs = new XYZ(xyz9.X, ptMaxEcs.Y, ptMaxEcs.Z);
							}
						}
					}
				}
			}
			catch
			{
			}
		}

		private static double GetWindDoorWholeWidth(List<IPlanarGeo> lstWindDoorGeoWithDimRef)
		{
			if (lstWindDoorGeoWithDimRef.Count == 0)
			{
				return 0.0;
			}
			double num = double.MaxValue;
			double num2 = double.MinValue;
			foreach (IPlanarGeo planarGeo in lstWindDoorGeoWithDimRef)
			{
				if (planarGeo.Weight != 11)
				{
					if (MathUtility.GreaterThan(num, planarGeo.Min2DPointECS.X, 1E-06))
					{
						num = planarGeo.Min2DPointECS.X;
					}
					if (MathUtility.LessThan(num2, planarGeo.Max2DPointECS.X, 1E-06))
					{
						num2 = planarGeo.Max2DPointECS.X;
					}
				}
			}
			return num2 - num;
		}

		private static Document m_doc;

		public static List<WallDataEx> m_lstAllDoorWinInfo = new List<WallDataEx>();

		private static double m_dval = AssistFunc.mmToFeet(100.0);

		private static double m_dDimMoveVal = AssistFunc.mmToFeet(500.0);

		private static double m_dOffsetVal = AssistFunc.mmToFeet(5000.0);

		private static List<KeyValuePair<int, double>> m_dicPreTextBoxZ = new List<KeyValuePair<int, double>>();

		private static CurveLoop m_previousTextBox = new CurveLoop();

		private static RevitPolygonRelateOperater m_useRelateOperater = new RevitPolygonRelateOperater();

		private static TopologyRelateKindEnum tempRelate;
	}
}
